package com.swak.frame.handler;

import java.util.Set;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;

import org.apache.commons.collections4.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.swak.frame.dto.base.RestApiCode;
import com.swak.frame.dto.base.SysRestCode;
import com.swak.frame.dto.response.Response;
import com.swak.frame.exception.ApiException;
import com.swak.frame.exception.BaseException;

/**
 * ResponseHandler ClassName: ResponseHandler.java
 * 
 * @author colley.ma
 * @date 2021年3月19日 下午2:40:53
 */
public class ResponseHandler {

	private static Logger logger = LoggerFactory.getLogger(ResponseHandler.class);

	public static Object handle(Class<?> returnType, String errCode, String errMsg) {
		if (isSwakResponse(returnType)) {
			return handleSwakResponse(returnType, errCode, errMsg);
		}
		throw new ApiException(errCode, errMsg);
	}

	public static Object handle(Class<?> returnType, RestApiCode errorCode) {
		return handle(returnType, errorCode.getRetCode(), errorCode.getRetMessage());
	}

	public static Object handle(Class<?> returnType, Exception e) {
		if (isSwakResponse(returnType)) {
			return handleSwakResponse(returnType, e);
		}
		if (BaseException.class.isInstance(e)) {
			BaseException ex = (BaseException) e;
			throw ex;
		}
		throw new ApiException(SysRestCode.SYS_ERR, e);
	}

	private  static Object handleSwakResponse(Class<?> returnType, String errCode, String errMsg) {
		try {
			Response response = (Response) returnType.newInstance();
			response.setRetCode(errCode);
			response.setRetMessage(errMsg);
			return response;
		} catch (Exception ex) {
			logger.error("[swak-response] - handleSwakResponse error:"+ex.getMessage(), ex);
			return new Response(SysRestCode.SYS_ERR);
		}
	}

	public static Object handleSwakResponse(Class<?> returnType, Exception e) {
		if (BaseException.class.isInstance(e)) {
			BaseException ex = (BaseException) e;
			return handleSwakResponse(returnType, ex.getErrCode(), ex.getErrMessage());
		}
		return handleSwakResponse(returnType, SysRestCode.SYS_ERR.getRetCode(),
				SysRestCode.SYS_ERR.getRetMessage());
	}

	public static Response handerConstraintViolationException(Exception ex) {
		if (ConstraintViolationException.class.isInstance(ex)) {
			ConstraintViolationException violationException = (ConstraintViolationException) ex;
			Set<ConstraintViolation<?>> violations = violationException.getConstraintViolations();
			if (CollectionUtils.isNotEmpty(violations)) {
				for (ConstraintViolation<?> item : violations) {
					return new Response(SysRestCode.INVALID_PARAM.getRetCode(), item.getMessage());
				}
			}
		}
		return new Response(SysRestCode.SYS_ERR);
	}

	private static boolean isSwakResponse(Class<?> returnType) {
		return Response.class.isAssignableFrom(returnType);
	}
	
}
